<?php
/** ============================================================
 * Class for creation of detailed paging info
 * @todo add capability to set page=all for skiping paging
 * ============================================================ */

class Pager
{
    /** Rows count
     * @var integer
     */
    var $cnt=0;

    /** Current page
     * @var integer
     */
    var $page=1;

    /** Rows per page
     * @var integer
     */
    var $pageSize=25;

    /** Pages per frame
     * @var integer
     */
    var $frameSize=10;

    /** Count of pages
     * @var integer
     */
    var $pagesCount=0;

    /** First row
     * @var integer
     */
    var $firstRow=0;

    /** Last row
     * @var integer
     */
    var $lastRow=0;

    /** URL key for page param e.g. in http://example.com/?page=3 it is 'page'
     * @var string
     */
    var $urlKey = 'page';

    /** URL object
     * @var object
     */
    var $url = null;

    /** Creates pager
     * @param Url $url current url
     * @param int $pageSize
     * @return object Pager
     * @access public
     */
    function Pager($url, $pageSize=0, $urlKey='page')
    {
        $this->urlKey   = $urlKey;
        $this->page     = intVal($url->getParam($urlKey));
        $this->pageSize = max(intVal($pageSize), 1);
        $this->url      = $url;
    }

    /**
     * Inits pager (calculates first/last rows, pageCount, correct page)
     * @param int $cnt rows count
     * @return string sql limit statement like '0,25'
     * @access public
     * @see Pager::getLimit()
     */
    function init($cnt)
    {
        $this->cnt        = max(intVal($cnt), 0);
        $this->pagesCount = ceil($this->cnt / $this->pageSize);
        $this->page       = max(1, min($this->pagesCount, $this->page));
        $this->firstRow   = $this->pageSize*($this->page-1);
        $this->lastRow    = min($this->firstRow + $this->pageSize, $this->cnt);
        return $this->getLimit();
    }

    /** Returns paging info: 'totalPages', 'totalRows', 'current', 'fromRow','toRow', 'firstUrl', 'prevUrl', 'nextUrl', 'lastUrl',  'urls' (url=>page)
     * @return array paging info
     * @access public
     */
    function getInfo($alias = array())
    {
        $aInfo = array(
            'totalPages' => $this->pagesCount,
            'totalRows'  => $this->cnt,
            'current'    => $this->page,
            'fromRow'    => $this->firstRow+1,
            'toRow'      => $this->lastRow,
            'firstUrl'   => '',
            'prevUrl'   => '',
            'nextUrl'   => '',
            'lastUrl'   => '',
        );        
        $oldKey = $this->url->getParam($this->urlKey);
        if (1 != $this->page)
        {
            $this->url->setParam($this->urlKey, 1);
            $aInfo['firstUrl'] = $this->url->getUrl($alias);

            $this->url->setParam($this->urlKey, $this->page-1);
            $aInfo['prevUrl'] = $this->url->getUrl($alias);
        }

        list($start, $finish) = $this->_getPos();
        for ($i=$start; $i<=$finish; ++$i)
        {
            if ($this->page == $i)
                $aInfo['urls'][''] = $i;
            else
            {
                $this->url->setParam($this->urlKey, $i);
                $aInfo['urls'][$this->url->getUrl($alias)] = $i;
            }
        }

        if ($this->pagesCount != $this->page)
        {
            $this->url->setParam($this->urlKey, $this->page+1);
            $aInfo['nextUrl'] = $this->url->getUrl($alias);
            $this->url->setParam($this->urlKey, $this->pagesCount);
            $aInfo['lastUrl']= $this->url->getUrl($alias);
        }
        $this->url->setParam($this->urlKey, $oldKey);
        
        return $aInfo;
    }

    
    /** Returns paging info for visitor: 
     *   'totalPages', 'totalRows', 'current', 'fromRow','toRow', 'firstUrl', 'prevUrl', 'nextUrl', 'lastUrl',  'urls' (url=>page)
     * @return array paging info
     * @access public
     */
    function getVisitorInfo($pageName)
    {
        $aInfo = array(
            'totalPages' => $this->pagesCount,
            'totalRows'  => $this->cnt,
            'current'    => $this->page,
            'fromRow'    => $this->firstRow+1,
            'toRow'      => $this->lastRow,
            'firstUrl'   => '',
            'prevUrl'   => '',
            'nextUrl'   => '',
            'lastUrl'   => '',
        );
        $url = $pageName."-";
        for ($i=1; $i < func_num_args(); $i++)
            $url .= func_get_arg($i)."-";
        for ($i=0; $i < $this->pagesCount; $i++)
            $res['urls'][$i+1] = $url.($i+1).".html";

        if (1 != $this->page)
        {
            $aInfo['firstUrl'] = $url.($i+1).".html";
            $aInfo['prevUrl'] = $url.($this->page-1).".html";
        }

        list($start, $finish) = $this->_getPos();

        for ($i=$start; $i<=$finish; ++$i)
        {
            if ($this->page == $i)
                $aInfo['urls'][''] = $i;
            else
            {
                $aInfo['urls'][$url.($i).".html"] = $i;
            }
        }

        if ($this->pagesCount != $this->page)
        {
            //$this->url->setParam($this->urlKey, $this->page+1);
            $aInfo['nextUrl'] = $url.($this->page+1).".html";//$this->url->getUrl();
            //$this->url->setParam($this->urlKey, $this->pagesCount);
            $aInfo['lastUrl']= $url.($this->pagesCount).".html";//$this->url->getUrl();
        }
/*                $res = array(   'totalPages' => $this->pagesCount,
                        'totalRows'  => $this->cnt,
                        'current'    => $this->page);
        $res['urls'] = array();
        for ($i=0; $i < $this->pagesCount; $i++)
            $res['urls'][$i+1] = $url.($i+1).".html";*/
        return $aInfo;
    }
    /** Gets data for sql limit statement
     * @return string like '0,25'
     * @access public
     */
    function getLimit()
    {
        return $this->firstRow.','.$this->pageSize;
    }


    /** Calculates first/last page in a current frame
     * @return array ($start, $finish)
     * @access private
     */
    function _getPos()
    {
        $start = 1;
        if (($this->page - $this->frameSize/2)>0)
        {
            if (($this->page + $this->frameSize/2) > $this->pagesCount)
                $start = (($this->pagesCount - $this->frameSize)>0) ? ( $this->pagesCount - $this->frameSize + 1) : 1;
            else
                $start = $this->page - floor($this->frameSize/2);
        }

        $finish = (($start + $this->frameSize - 1) < $this->pagesCount) ? ($start + $this->frameSize - 1) : $this->pagesCount;
        return array($start, $finish);
    }
}